package cn.com.nes.common.util;

import com.alibaba.fastjson2.JSONObject;
import org.springframework.http.*;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class DouYinAPIUtils {

    private static RestTemplate restTemplate = new RestTemplate();

    static {
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
//        restTemplate.getMessageConverters().add(0, new FastJsonHttpMessageConverter());
    }

    private final static String CLIENT_KEY = "awy0rlhwrbmjm85l";
    private final static String CLIENT_SECRET = "2c8131292380b29a5994028d9a3aab92";

    /**
     * 调用抖音获取 access_token接口，返回JSONObject对象
     *
     * @param code 授权码
     * @return
     * @throws Exception
     */
    public static JSONObject accessToken(String code) throws Exception {
        String url = "https://open.douyin.com/oauth/access_token/";
        MultiValueMap<String, String> reqBody = new LinkedMultiValueMap<>();
        reqBody.add("client_key", CLIENT_KEY);
        reqBody.add("client_secret", CLIENT_SECRET);
        reqBody.add("grant_type", "authorization_code");
        reqBody.add("code", code);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(reqBody, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, JSONObject.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 刷新 refresh_token接口，返回JSONObject对象
     *
     * @param refreshToken refresh_token 参数
     * @return
     * @throws Exception
     */
    public static JSONObject renewRefreshToken(String refreshToken) throws Exception {
        String url = "https://open.douyin.com/oauth/renew_refresh_token/";
        MultiValueMap<String, String> reqBody = new LinkedMultiValueMap<>();
        reqBody.add("client_key", CLIENT_KEY);
        reqBody.add("refresh_token", refreshToken);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(reqBody, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, JSONObject.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 生成 client_token 接口，返回JSONObject对象
     *
     * @return
     * @throws Exception
     */
    public static JSONObject clientToken() throws Exception {
        String url = "https://open.douyin.com/oauth/renew_refresh_token/";
        MultiValueMap<String, String> reqBody = new LinkedMultiValueMap<>();
        reqBody.add("client_key", CLIENT_KEY);
        reqBody.add("client_secret", CLIENT_KEY);
        reqBody.add("grant_type", "client_credential");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(reqBody, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, JSONObject.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 刷新 access_token 接口， 返回JSONObject对象
     *
     * @param refreshToken refresh_token 参数
     * @return
     * @throws Exception
     */
    public static JSONObject refreshAccessToken(String refreshToken) throws Exception {
        String url = "https://open.douyin.com/oauth/refresh_token/";
        MultiValueMap<String, String> reqBody = new LinkedMultiValueMap<>();
        reqBody.add("client_key", CLIENT_KEY);
        reqBody.add("grant_type", "refresh_token");
        reqBody.add("refresh_token", refreshToken);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(reqBody, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, JSONObject.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 获取用户公开信息接口，获取用户信息，返回JSONObject 对象
     *
     * @param accessToken 接口调用凭证
     * @param openId      用户在抖音平台唯一标识
     * @return
     * @throws Exception
     */
    public static JSONObject userInfo(String accessToken, String openId) throws Exception {
        String url = "https://open.douyin.com/oauth/userinfo/";
        Map<String, String> reqBody = new HashMap<>();
        reqBody.put("access_token", accessToken);
        reqBody.put("open_id", openId);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access_token", accessToken);
        HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(reqBody, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, JSONObject.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 获取粉丝列表接口，返回JSONObject 对象
     *
     * @param accessToken 接口调用凭证
     * @param openId      抖音用户唯一标识
     * @param cursor      页码，从 0 开始
     * @return
     * @throws Exception
     */
    public static JSONObject fansList(String accessToken, String openId, int cursor) throws Exception {
        String url = "https://open.douyin.com/fans/list/?open_id={open_id}&cursor={cursor}&count={count}";
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("open_id", openId);
        reqBody.put("cursor", cursor);
        reqBody.put("count", 20);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<?> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class, reqBody);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 获取关注列表接口，返回JSONObject 对象
     *
     * @param accessToken 接口调用凭证
     * @param openId      抖音用户唯一标识
     * @param cursor      页码，从 0 开始
     * @return
     * @throws Exception
     */
    public static JSONObject followingList(String accessToken, String openId, int cursor) throws Exception {
        String url = "https://open.douyin.com/following/list/?open_id={open_id}&cursor={cursor}&count={count}";
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("open_id", openId);
        reqBody.put("cursor", cursor);
        reqBody.put("count", 20);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<?> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class, reqBody);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 获取关注列表接口，返回JSONObject 对象
     *
     * @param accessToken    接口调用凭证
     * @param openId         抖音用户唯一标识
     * @param followerOpenId 抖音关注用户唯一标识
     * @return
     * @throws Exception
     */
    public static JSONObject fansCheck(String accessToken, String openId, String followerOpenId) throws Exception {
        String url = "https://open.douyin.com/fans/check/?open_id={open_id}&follower_open_id={follower_open_id}";
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("open_id", openId);
        reqBody.put("follower_open_id", followerOpenId);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<?> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class, reqBody);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 调用抖音 获取视频列表，返回JSONObject 对象
     *
     * @param accessToken 接口调用凭证
     * @param openId      抖音用户唯一标识
     * @param cursor      页码，从 0 开始
     * @return
     * @throws Exception
     */
    public static JSONObject videoList(String accessToken, String openId, int cursor) throws Exception {
        String url = "https://open.douyin.com/video/list/?open_id={open_id}&cursor={cursor}&count={count}";
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("open_id", openId);
        reqBody.put("cursor", cursor);
        reqBody.put("count", 20);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<?> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class, reqBody);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 查询特定视频的视频数据
     *
     * @param accessToken 接口调用凭证
     * @param openId      抖音用户唯一标识
     * @param itemIds     视频ID
     * @return
     * @throws Exception
     */
    public static JSONObject videoData(String accessToken, String openId, String[] itemIds) throws Exception {
        UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://open.douyin.com/video/data/").queryParam("open_id", openId).build();
        URI uri = uriComponents.toUri();
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("item_ids", itemIds);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(requestBody, headers);
        Map<String, Object> params = new HashMap<>();
        params.put("open_id", openId);
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(uri, httpEntity, JSONObject.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 关键词视频搜索
     *
     * @param accessToken 接口调用凭证
     * @param openId      抖音用户唯一标识
     * @param cursor      视频ID
     * @param keyword     关键词
     * @return
     * @throws Exception
     */
    public static JSONObject videoSearch(String accessToken, String openId, int cursor, String keyword) throws Exception {
        String url = "https://open.douyin.com/video/search/?open_id={open_id}&cursor={cursor}&count={count}&keyword={keyword}";
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("open_id", openId);
        reqBody.put("cursor", cursor);
        reqBody.put("count", 20);
        reqBody.put("keyword", keyword);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<?> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class, reqBody);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 关键词视频评论列表
     *
     * @param accessToken 接口调用凭证
     * @param secItemId   视频搜索接口返回的加密的视频id
     * @param cursor      页码，从 0 开始
     * @return
     */
    public static JSONObject videoSearchCommentList(String accessToken, String secItemId, int cursor) {
        String url = "https://open.douyin.com/video/search/comment/list/?sec_item_id={sec_item_id}&cursor={cursor}&count={count}";
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("sec_item_id", secItemId);
        reqBody.put("cursor", cursor);
        reqBody.put("count", 20);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<?> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class, reqBody);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 获取视频点赞数据
     *
     * @param accessToken 接口调用凭证
     * @param openId   视频搜索接口返回的加密的视频id
     * @param itemId      页码，从 0 开始
     * @return
     */
    public static JSONObject dataExternalItemLike(String accessToken, String openId, String itemId, int dateType) {
        String url = "https://open.douyin.com/data/external/item/like/?open_id={open_id}&item_id={item_id}&date_type={date_type}";
        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("open_id", openId);
        reqBody.put("item_id", itemId);
        reqBody.put("date_type", dateType);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("access-token", accessToken);
        HttpEntity<?> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, JSONObject.class, reqBody);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return null;
    }


}
